/**
 * 
 */
package game.render.screen;

import game.GameMidlet;
import game.Util;
import game.model.Actor;
import game.model.ActorFactory;
import game.model.AttackInfo;
import game.model.Char;
import game.model.CharInfo;
import game.model.CharShadow;
import game.model.Command;
import game.model.EffectManager;
import game.model.Explosion;
import game.model.IAction;
import game.model.LiveActor;
import game.model.Monster;
import game.model.MonsterInfo;
import game.model.Tilemap;
import game.model.arrow.Arrow;
import game.model.arrow.IArrow;
import game.networklogic.GameService;
import game.networklogic.IGameLogicHandler;
import game.render.Canvas;
import game.render.Res;

import java.util.Vector;

import javax.microedition.lcdui.Display;
import javax.microedition.lcdui.Graphics;

import network.Session_ME;

/**
 * @author Quynh Lam
 * 
 */
public class GameScr extends Screen implements IGameLogicHandler {

    public int gssx, gssy, gssw, gssh, gssxe, gssye;
    int CMVIBRATEX[] = { -1, 2, 1, -2 };
    int CMVIBRATEY[] = { -3, 2, -1, 1 };
    int currentCmVibrate = -1;
    public static int cmtoX, cmtoY, cmvx, cmvy, cmdx, cmdy, cmx, cmy, cmxLim, cmyLim;
    public Vector actors = new Vector();
    public Vector arrows = new Vector();
    public Char mainChar;
    public Actor focusedActor;
    boolean readyGetGameLogic;
    public CharShadow shadow;
    long lastUpdateMyPositionTime;

    boolean changeSinceLastUpdate;
    public int gsw, gsh, gscmdBarY, gshw, gshh, gswd3, gshd3, gsw2d3, gsh2d3, gsw3d4, gsh3d4, gswd6, gshd6;
    public GameService gameService = GameService.gI();

    public GameScr() {

    }

    public void loadCamera() {
        gsw = Canvas.w;
        gsh = Canvas.h - 48;
        gshw = gsw >> 1;
        gshh = gsh >> 1;
        gswd3 = gsw / 3;
        gshd3 = gsh / 3;
        gsw2d3 = 2 * gsw / 3;
        gsh2d3 = 2 * gsh / 3;
        gsw3d4 = 3 * gsw / 4;
        gsh3d4 = 3 * gsh / 4;
        gswd6 = gsw / 6;
        gshd6 = gsh / 6;
        // Map --------------------
        gssw = (gsw >> 4) + 2;
        gssh = (gsh >> 4) + 2;
        if (gsw % 24 != 0)
            gssw += 1;
        cmxLim = ((Tilemap.w - 1) << 4) - gsw;
        cmyLim = ((Tilemap.h - 1) << 4) - gsh;
        cmx = cmtoX = mainChar.x - gshw;
        cmy = cmtoY = mainChar.y - gshh;
        if (cmx < 0)
            cmx = 0;
        if (cmx > cmxLim)
            cmx = cmxLim;
        if (cmy < 0)
            cmy = 0;
        if (cmy > cmyLim)
            cmy = cmyLim;
        //
        gssx = (cmx >> 4) - 1;
        if (gssx < 0)
            gssx = 0;
        gssy = cmy >> 4;
        gssxe = gssx + gssw;
        gssye = gssy + gssh;
        if (gssy < 0)
            gssy = 0;
        if (gssye > Tilemap.h - 1)
            gssye = Tilemap.h - 1;
    }

    private final void updateCamera() {
        if (cmx != cmtoX || cmy != cmtoY) {
            cmvx = (cmtoX - cmx) << 2;
            cmvy = (cmtoY - cmy) << 2;
            cmdx += cmvx;
            cmx += cmdx >> 4;
            cmdx = cmdx & 0xf;
            cmdy += cmvy;
            cmy += cmdy >> 4;
            cmdy = cmdy & 0xf;
            if (cmx < 0)
                cmx = 0;
            if (cmx > cmxLim)
                cmx = cmxLim;
            if (cmy < 0)
                cmy = 0;
            if (cmy > cmyLim)
                cmy = cmyLim;
        }
        if (currentCmVibrate >= 0) {
            cmx += CMVIBRATEX[currentCmVibrate];
            cmy += CMVIBRATEY[currentCmVibrate];
            currentCmVibrate++;
            if (currentCmVibrate == 4)
                currentCmVibrate = -1;
            if (cmx < 0)
                cmx = 0;
            if (cmx > cmxLim)
                cmx = cmxLim;
            if (cmy < 0)
                cmy = 0;
            if (cmy > cmyLim)
                cmy = cmyLim;
        }
        gssx = (cmx >> 4) - 1;
        if (gssx < 0)
            gssx = 0;
        gssy = cmy >> 4;
        gssxe = gssx + gssw;
        gssye = gssy + gssh;
        if (gssy < 0)
            gssy = 0;
        if (gssye > Tilemap.h - 1)
            gssye = Tilemap.h - 1;
    }

    public long lastTimePing;
    public long pingDelay;
    private int pingNextIn = 10;

    public void update() {
        updateCamera();
        updateKey();
        sendUpdateMyCharInfoToServer();
        cmtoX = mainChar.x - gshw;
        cmtoY = mainChar.y - gshh;
        for (int i = arrows.size() - 1; i >= 0; i--) {
            Arrow a = (Arrow) arrows.elementAt(i);
            a.update();
            if (a.wantDestroy) {
                arrows.removeElementAt(i);
            }
        }
        for (int i = actors.size() - 1; i >= 0; i--) {
            Actor a = (Actor) (actors.elementAt(i));
            a.update();
            // Check if too far from char. Destroy it
            if (!Util.inDataRange(a, mainChar))
                a.wantDestroy = true;
            //
            if (a.wantDestroy) {
                if (focusedActor == a)
                    focusedActor = null;
                actors.removeElementAt(i);
            }
        }

        Util.quickSort(actors);
        if (Canvas.gameTick % 10 == 0) {
            focusedActor = findFocusActor();
        }
        EffectManager.lowEffects.updateAll();
        EffectManager.hiEffects.updateAll();
        if (pingNextIn > 0) {
            pingNextIn--;
            if (pingNextIn == 0) {
                lastTimePing = System.currentTimeMillis();
                gameService.ping();
            }
        }
    }

    /**
     * @return
     */
    static final int[][] C = { { -100, +100, 1, 128 }, { -100, 100, -128, -1 }, { -128, -1, -100, 100 }, { 1, 128, -100, 100 } };

    public Actor findFocusActor() {
        int left = mainChar.x + C[mainChar.dir][0];
        int right = mainChar.x + C[mainChar.dir][1];
        int up = mainChar.y + C[mainChar.dir][2];
        int down = mainChar.y + C[mainChar.dir][3];
        int shorted = 10000, shortedIndex = -1;
        for (int i = 0; i < actors.size(); i++) {
            Actor a = (Actor) actors.elementAt(i);
            if (a.x > left && a.x < right && a.y > up && a.y < down && a != shadow && (a.type == 0 || a.type == 1)) {
                int distance = Util.abs(mainChar.x - a.x) + Util.abs(mainChar.y - a.y);
                if (distance < shorted) {
                    shorted = distance;
                    shortedIndex = i;
                }
            }
        }
        if (shortedIndex == -1)
            return null;
        else
            return (Actor) actors.elementAt(shortedIndex);
    }

    /**
     * 
     */
    static final short DX[][] = { { 0, 0, -48, 48 }, { 0, 0, -32, 32 }, { 0, 0, -16, 16 }, { 0, 0, 0, 0 } };
    static final short DY[][] = { { 48, -48, 0, 0 }, { 32, -32, 0, 0 }, { 16, -16, 0, 0 }, { 0, 0, 0, 0 } };
    private static final int DELAY_BETWEEN_PING = 30;

    private void sendUpdateMyCharInfoToServer() {
        long now = System.currentTimeMillis();
        try {
            if (now - lastUpdateMyPositionTime > 500) {
                lastUpdateMyPositionTime = now;
                if (changeSinceLastUpdate) {
                    changeSinceLastUpdate = false;
                    int xGuess = mainChar.x, yGuess = mainChar.y, d = 0;
                    while (d <= 3) {
                        xGuess = mainChar.x + DX[d][mainChar.dir];
                        yGuess = mainChar.y + DY[d][mainChar.dir];
                        if (!Tilemap.tileTypeAtPixel(xGuess, yGuess, Tilemap.T_BLOCK))
                            break;
                        d++;
                    }
                    gameService.moveChar(xGuess, yGuess);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }

    }

    /**
     * 
     */
    private void updateKey() {

        if (mainChar.justStopFromRun) {
            mainChar.justStopFromRun = false;
            changeSinceLastUpdate = true;
            lastUpdateMyPositionTime = 0;
            gameService.moveChar(mainChar.x, mainChar.y);
            changeSinceLastUpdate = false;

        }
        boolean forceMoveUp = false;
        boolean forceMoveDown = false;
        boolean forceMoveLeft = false;
        boolean forceMoveRight = false;
        if (Canvas.keyPressed[1]) {
            Canvas.keyPressed[1] = false;
            mainChar.currentBody++;
            if (mainChar.currentBody >= Res.imgCharBody.length)
                mainChar.currentBody = 0;
        }
        if (Canvas.keyPressed[3]) {
            Canvas.keyPressed[3] = false;
            mainChar.currentLeg++;
            if (mainChar.currentLeg >= Res.imgCharLeg.length)
                mainChar.currentLeg = 0;
        }
        if (Canvas.keyPressed[7]) {
            Canvas.keyPressed[7] = false;
            mainChar.currentHead++;
            if (mainChar.currentHead >= Res.imgCharHead.length)
                mainChar.currentHead = 0;
        }
        if (Canvas.keyPressed[9]) {
            Canvas.keyPressed[9] = false;
            mainChar.currentHat++;
            if (mainChar.currentHat >= Res.imgCharHat.length)
                mainChar.currentHat = 0;
        }
        if (Canvas.keyPressed[11]) {
            Canvas.keyPressed[11] = false;
            mainChar.skillID++;
            if (mainChar.skillID > 5)
                mainChar.skillID = 0;
            mainChar.setCurrentSkill(mainChar.skillID);
        }
        if (mainChar.act == Char.A_RUN || mainChar.act == Char.A_STAND) {
            if (Canvas.keyPressed[5]) {
                Canvas.keyPressed[5] = false;

                if (focusedActor != null && (focusedActor.type == 0 || focusedActor.type == 1)) {
                    LiveActor attackedLiveActor = (LiveActor) focusedActor;
                    if (attackedLiveActor.realHP <= 0)
                        return;
                    // Go there if out of Range
                    if (Util.abs(mainChar.y - attackedLiveActor.y) > mainChar.skillRange) {
                        if (mainChar.y < attackedLiveActor.y)
                            forceMoveDown = true;
                        else
                            forceMoveUp = true;
                    } else if (Util.abs(mainChar.x - attackedLiveActor.x) > mainChar.skillRange) {
                        if (mainChar.x < attackedLiveActor.x)
                            forceMoveRight = true;
                        else
                            forceMoveLeft = true;
                    } else {
                        // Check if can Attack
                        long now = System.currentTimeMillis();
                        if (now - mainChar.timeLastUseSkill > mainChar.delayLastSkill) {
                            mainChar.dir = Util.findDirection(mainChar, attackedLiveActor);
                            mainChar.startAttack(attackedLiveActor, 0, mainChar.skillID);
                            gameService.moveChar(mainChar.x, mainChar.y);
                            changeSinceLastUpdate = false;
                            switch (attackedLiveActor.type) {
                            case 0:
                                gameService.attackOtherPlayer(attackedLiveActor.ID, mainChar.skillID);
                                break;
                            case 1:
                                gameService.attackMonster(attackedLiveActor.ID, mainChar.skillID);
                                break;
                            }
                            return;
                        }
                    }
                }
            }
            boolean changeDirection = false;
            if (Canvas.keyPressed[2]) {
                Canvas.keyPressed[2] = false;
                changeDirection = true;
            }
            if (Canvas.keyPressed[4]) {
                Canvas.keyPressed[4] = false;
                changeDirection = true;
            }
            if (Canvas.keyPressed[6]) {
                Canvas.keyPressed[6] = false;
                changeDirection = true;
            }
            if (Canvas.keyPressed[8]) {
                Canvas.keyPressed[8] = false;
                changeDirection = true;
            }
            if (changeDirection) {
                gameService.moveChar(mainChar.x, mainChar.y);
            }
            boolean move = false;
            short moveToX = 0, moveToY = 0;
            if (Canvas.keyHold[2] || forceMoveUp) {
                move = true;
                mainChar.dir = Char.UP;
                moveToX = mainChar.x;
                moveToY = (short) (mainChar.y - 16);
                if (Tilemap.tileTypeAtPixel(moveToX + 16, moveToY - 8, Tilemap.T_BLOCK) || Tilemap.tileTypeAtPixel(moveToX - 16, moveToY - 8, Tilemap.T_BLOCK)) {
                    moveToY = (short) (Tilemap.tileYofPixel(moveToY - 8) + 16 + 8);
                    if (mainChar.y == moveToY) {
                        if (!Tilemap.tileTypeAtPixel(moveToX + 16, moveToY - 16, Tilemap.T_BLOCK)) {
                            moveToX += 16;
                        } else if (!Tilemap.tileTypeAtPixel(moveToX - 16, moveToY - 16, Tilemap.T_BLOCK)) {
                            moveToX -= 16;
                        } else
                            move = false;
                    }
                }
            }
            if (Canvas.keyHold[8] || forceMoveDown) {
                move = true;
                mainChar.dir = Char.DOWN;
                moveToX = mainChar.x;
                moveToY = (short) (mainChar.y + 16);
                if (Tilemap.tileTypeAtPixel(moveToX + 16, moveToY + 8, Tilemap.T_BLOCK) || Tilemap.tileTypeAtPixel(moveToX - 16, moveToY + 8, Tilemap.T_BLOCK)) {
                    moveToY = (short) (Tilemap.tileYofPixel(moveToY + 8) - 9);
                    if (mainChar.y == moveToY) {
                        if (!Tilemap.tileTypeAtPixel(moveToX + 16, moveToY + 16, Tilemap.T_BLOCK)) {
                            moveToX += 16;
                        } else if (!Tilemap.tileTypeAtPixel(moveToX - 16, moveToY + 16, Tilemap.T_BLOCK)) {
                            moveToX -= 16;
                        } else
                            move = false;
                    }
                }
            }
            if (Canvas.keyHold[4] || forceMoveLeft) {
                move = true;
                mainChar.dir = Char.LEFT;
                moveToX = (short) (mainChar.x - 16);
                moveToY = mainChar.y;
                if (Tilemap.tileTypeAtPixel(moveToX - 16, moveToY - 8, Tilemap.T_BLOCK) || Tilemap.tileTypeAtPixel(moveToX - 16, moveToY + 8, Tilemap.T_BLOCK)) {
                    moveToX = (short) (Tilemap.tileYofPixel(moveToX - 16) + 16 + 16);
                    if (mainChar.x == moveToX) {
                        if (!Tilemap.tileTypeAtPixel(moveToX - 32, moveToY + 16, Tilemap.T_BLOCK)) {
                            moveToY += 16;
                        } else if (!Tilemap.tileTypeAtPixel(moveToX - 32, moveToY - 16, Tilemap.T_BLOCK)) {
                            moveToY -= 16;
                        } else
                            move = false;
                    }
                }
            }
            if (Canvas.keyHold[6] || forceMoveRight) {
                move = true;
                mainChar.dir = Char.RIGHT;
                moveToY = mainChar.y;
                moveToX = (short) (mainChar.x + 16);
                if (Tilemap.tileTypeAtPixel(moveToX + 16, moveToY - 8, Tilemap.T_BLOCK) || Tilemap.tileTypeAtPixel(moveToX + 16, moveToY + 8, Tilemap.T_BLOCK)) {
                    moveToX = (short) (Tilemap.tileYofPixel(moveToX + 16) - 17);
                    if (mainChar.x == moveToX) {
                        if (!Tilemap.tileTypeAtPixel(moveToX + 32, moveToY + 16, Tilemap.T_BLOCK)) {
                            moveToY += 16;
                        } else if (!Tilemap.tileTypeAtPixel(moveToX + 32, moveToY - 16, Tilemap.T_BLOCK)) {
                            moveToY -= 16;
                        } else
                            move = false;
                    }
                }
            }
            if (move) {
                mainChar.moveTo(moveToX, moveToY);
                changeSinceLastUpdate = true;
            }
        }

    }

    public void paint(Graphics g) {
        g.translate(-g.getTranslateX(), -g.getTranslateY());
        g.translate(-cmx, -cmy);
        Tilemap.paintTile(g);
        EffectManager.lowEffects.paintAll(g);
        Actor tem;
        for (int i = 0; i < actors.size(); i++) {
            tem = ((Actor) (actors.elementAt(i)));
            tem.paint(g);
            if (tem == focusedActor) {
                g.drawImage(Res.imgSelect, tem.x, tem.y - tem.height, Graphics.HCENTER | Graphics.BOTTOM);
                if (tem.type == 1) {
                    ((Monster) tem).paintHPBar(g);
                }
            }
        }
        IArrow arrow;
        for (int i = 0; i < arrows.size(); i++) {
            arrow = ((IArrow) (arrows.elementAt(i)));
            arrow.paint(g);
        }
        EffectManager.hiEffects.paintAll(g);
        g.translate(-g.getTranslateX(), -g.getTranslateY());
        g.translate(-cmx, -cmy);
        Tilemap.paintTileTop(g);
        //
        paintCommandBar(g);

    }

    public void startNewArrow(int type, Char from, LiveActor to, int x, int y, int power) {
        IArrow a = new Arrow();
        a.set(type, x, y, power, from, to);
        arrows.addElement(a);
    }

    /**
     * @param g
     * 
     */
    private void paintCommandBar(Graphics g) {
        g.translate(-g.getTranslateX(), -g.getTranslateY());
        int send = Session_ME.gI().sendByteCount;
        int rcv = Session_ME.gI().recvByteCount;
        g.setColor(0);
        g.fillRect(0, gsh, gsw, Canvas.h - gsh);
        game.render.Font.drawFontBString(g, "Map:" + map + " S:" + send + " R:" + rcv + " T:" + (send + rcv) + " Ping:" + pingDelay, 10, gsh + 10, 0);
        game.render.Font.drawFontBString(g, "Skill:" + mainChar.skillID, 10, gsh + 25, 0);

    }

    /**
     * @param actorType
     * @param actorID
     * @param x2
     * @param y2
     */

    public void onActorMove(short actorType, short actorID, short x2, short y2) {
        if (!readyGetGameLogic)
            return;
        if (actorID == shadow.ID) {
            shadow.setPosTo(x2, y2);
            return;
        }
        for (int i = 0; i < actors.size(); i++) {
            Actor a = (Actor) actors.elementAt(i);
            if (a.ID == actorID) {
                a.setPosTo(x2, y2);
                return;
            }
        }
        Actor a = ActorFactory.CreateActor(actorType, actorID, x2, y2);
        actors.addElement(a);
        if (actors.size() < 10) {
            switch (actorType) {
            case 0:
                gameService.requestCharInfo(actorID);
                break;
            case 1:
                gameService.requestMonsterInfo(actorID);
                break;
            default:
                break;
            }
        }

    }

    /**
     * @param charInfo
     */
    public void onCharInfo(CharInfo charInfo) {
        if (!readyGetGameLogic)
            return;
        Char c = findCharByID(charInfo.id);
        if (c != null)
            c.setInfo(charInfo);
    }

    /**
     * @param attackInfo
     */
    public void onPlayerAttackPlayer(AttackInfo attackInfo) {
        if (!readyGetGameLogic)
            return;
        if (attackInfo.attacker == mainChar.ID) { // I'm the attacker
            Char attakedChar = findCharByID(attackInfo.attacked);
            if (attakedChar != null) {
                attakedChar.setRealHP(attackInfo.hpLeft);
            }
        } else if (attackInfo.attacked == mainChar.ID) { // i'm attacked
            Char attacker = findCharByID(attackInfo.attacker);
            if (attacker != null) {
                attacker.dir = Util.findDirection(attacker, mainChar);
                attacker.startAttack(mainChar, attackInfo.hpLost, attackInfo.skill);
            }
            mainChar.setRealHP(attackInfo.hpLeft);
        } else { // I'm observer
            Char attakedChar = findCharByID(attackInfo.attacked);
            if (attakedChar != null)
                attakedChar.setRealHP(attackInfo.hpLeft);
            Char attacker = findCharByID(attackInfo.attacker);
            if (attacker != null) {
                attacker.dir = Util.findDirection(attacker, attakedChar);
                attacker.startAttack(attakedChar, attackInfo.hpLost, attackInfo.skill);
            }
        }

    }

    // Player Attack Monster
    public void onPlayerAttackMonster(AttackInfo monsterAttackInfo) {
        if (!readyGetGameLogic)
            return;
        LiveActor m = findMonsterByID(monsterAttackInfo.attacked);
        if (m != null) {
            m.setRealHP(monsterAttackInfo.hpLeft);
        }
        if (mainChar.ID == monsterAttackInfo.attacker)
            return;
        else {
            Char c = findCharByID(monsterAttackInfo.attacker);
            if (c != null) {
                c.dir = Util.findDirection(c, m);
                c.startAttack(m, monsterAttackInfo.hpLost, monsterAttackInfo.skill);
            }
        }

    }

    /**
     * @param x
     * @param y
     */
    public void startExplosionAt(short x, short y) {
        actors.addElement(new Explosion(x, y));
    }

    private Char findCharByID(short id) {
        for (int i = 0; i < actors.size(); i++) {
            Actor a = (Actor) actors.elementAt(i);
            if (a.type == 0 && a.ID == id)
                return (Char) a;
        }
        return null;
    }

    private Monster findMonsterByID(short id) {
        for (int i = 0; i < actors.size(); i++) {
            Actor a = (Actor) actors.elementAt(i);
            if (a.type == 1 && a.ID == id)
                return (Monster) a;
        }
        return null;
    }

    public byte map;

    /**
     * @param mainCharInfo
     */
    public void onInfoMainChar(CharInfo mainCharInfo) {
        mainChar = new Char();
        mainChar.ID = mainCharInfo.id;
        mainChar.setInfo(mainCharInfo);
        shadow = new CharShadow();
        shadow.ID = mainChar.ID;
        shadow.x = mainChar.x;
        shadow.y = mainChar.y;
        actors.addElement(mainChar);
        actors.addElement(shadow);
        readyGetGameLogic = true;
    }

    /**
     * @param monsterInfo
     */
    public void onMonsterInfo(MonsterInfo monsterInfo) {
        if (!readyGetGameLogic)
            return;
        Monster m = findMonsterByID(monsterInfo.id);
        if (m != null)
            m.setInfo(monsterInfo);
    }

    /**
     * @param charID
     */
    public void charOutGame(short charID) {
        if (!readyGetGameLogic)
            return;
        for (int i = 0; i < actors.size(); i++) {
            Actor a = (Actor) actors.elementAt(i);
            if (a.type == 0 && a.ID == charID) {
                actors.removeElementAt(i);
                break;
            }
        }
    }

    /**
     * @param monsterAttackPlayerInfo
     */
    public void onMonsterAttackPlayer(AttackInfo monsterAttackPlayerInfo) {
        if (!readyGetGameLogic)
            return;
        Monster m = findMonsterByID(monsterAttackPlayerInfo.attacker);
        if (m != null) {
            m.startAttack();
            if (mainChar.ID == monsterAttackPlayerInfo.attacked) {
                mainChar.hp = monsterAttackPlayerInfo.hpLeft;
                m.dir = Util.findDirection(m, mainChar);
                if (focusedActor == null)
                    focusedActor = m;
            } else {
                Char c = findCharByID(monsterAttackPlayerInfo.attacked);
                if (c != null) {
                    c.hp = monsterAttackPlayerInfo.hpLeft;
                    m.dir = Util.findDirection(m, c);
                }
            }
        }
    }

    /**
     * 
     */
    public void onPingBack() {
        pingDelay = System.currentTimeMillis() - lastTimePing;
        // Ping again
        pingNextIn = DELAY_BETWEEN_PING;
    }

    /*
     * (non-Javadoc)
     * 
     * @see game.networklogic.IGameLogicHandler#onLoginSuccess()
     */
    public void onLoginSuccess() {
        Canvas.waitScr.setInfo("Login success. Waiting for Main Char Info");
    }

    /*
     * (non-Javadoc)
     * 
     * @see game.networklogic.IGameLogicHandler#onConnectOK()
     */
    public void onConnectOK() {
        // TODO Auto-generated method stub
        Canvas.waitScr.setInfo("Connect OK. Now login in.");
    }

    /*
     * (non-Javadoc)
     * 
     * @see game.networklogic.IGameLogicHandler#onConnectFail()
     */
    public void onConnectFail() {
        Canvas.messageScr.setInfo("Connect fail.", null, new Command("OK", new IAction() {
            public void perform() {
                Display.getDisplay(GameMidlet.instance).setCurrent(GameMidlet.loginForm);
            }
        }), null);
        Canvas.messageScr.switchToMe();

    }

    /*
     * (non-Javadoc)
     * 
     * @see game.networklogic.IGameLogicHandler#onDisconnect()
     */
    public void onDisconnect() {
        Canvas.messageScr.setInfo("Server shut down or network problem.", null, new Command("OK", new IAction() {
            public void perform() {
                Display.getDisplay(GameMidlet.instance).setCurrent(GameMidlet.loginForm);
            }
        }), null);

    }

    public void onMap(byte map) {
        try {
            this.map = map;
            Tilemap.loadMap(map);
            Canvas.gameScr.loadCamera();
            Canvas.gameScr.switchToMe();
        } catch (Exception e) {
        }

    }
}
